﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;

namespace WorldOnFire
{
    public class CJuggernaut : ABCEnemy
    {
        private float[] m_fBomberTimer;
        private int[] m_nBomberCount;
        private List<int>[] m_BomberIndexList;
        private bool[] m_bBombersReleased;

        private float[] m_fMissileTimer;
        private int[] m_nMissileCount;
        public float m_fSecondaryRange;

        private const float PLASMA_DAMAGE = 10.0f;
        private const float MISSILE_DAMAGE = 3.0f;

        public override void Initialize(int _nObjectCount)
        {
            // Initialize arrays
            m_fBomberTimer = new float[_nObjectCount];
            m_nBomberCount = new int[_nObjectCount];
            m_BomberIndexList = new List<int>[_nObjectCount];
            m_bBombersReleased = new bool[_nObjectCount];

            m_fMissileTimer = new float[_nObjectCount];
            m_nMissileCount = new int[_nObjectCount];

            // Initialize base members
            base.Initialize(_nObjectCount);

            // Initialize the members
            m_fOrbitAngleLock = 0.15f;

            for (int iObject = 0; iObject < _nObjectCount; ++iObject)
            {
                m_BomberIndexList[iObject] = new List<int>();

                m_fMass = 1000.0f;
                m_fEngineForce = 2.5f * m_fMass;
                m_fMaximumSpeed = 5.0f;
                m_fTurnSpeed = 0.05f * (float)Math.PI;

                m_fMinimumRange = 300.0f;
                m_fMaximumRange = 500.0f;
                m_fShotDelayPrimary = 10.0f;
                m_fShotDelaySecondary = 2.5f;
                m_fShotSpeed = 50.0f;
                m_fDamage = PLASMA_DAMAGE;
                m_fAreaOfEffect = 0.0f;
                m_fMaximumHealth = 1000.0f;

                // TODO: SET TARGET INDEX
                m_nTargetIndex[iObject] = 0;
                m_fDisabledTimer[iObject] = 0.0f;
                m_fShotTimerPrimary[iObject] = 0.0f;

                // TODO: LOLWUT
                this.SetAIState(iObject, eAIState.CLOSING);
            }
        }

        public override void LoadContent()
        {
            m_eModelID = CRenderingManager.eModelID.ENEMY_JUGGERNAUT;

            base.LoadContent();
        }

        public override void Update(float _fDeltaTime)
        {
            // Set the damage for missiles
            m_fDamage = MISSILE_DAMAGE;

            // Loop through each juggernaut
            for (int iObject = 0; iObject < m_nObjectCount; ++iObject)
            {
                // Decrement the missile timer
                m_fMissileTimer[iObject] -= _fDeltaTime;

                // If missiles need to be fired
                if (m_nMissileCount[iObject] > 0 && m_fMissileTimer[iObject] < 0.0f)
                {
                    // Fire a missile
                    s_ObjectManager.GetProjectile(ABCProjectile.eProjectileType.MISSILE)
                        .CreateProjectile(this, iObject, new Vector3(-6.5f, -4.5f, 25.0f));
                    s_ObjectManager.GetProjectile(ABCProjectile.eProjectileType.MISSILE)
                        .CreateProjectile(this, iObject, new Vector3(6.5f, -4.5f, 25.0f));

                    // Reset the missile timer and decrement the missiles remaining
                    m_fMissileTimer[iObject] = 0.15f;
                    --m_nMissileCount[iObject];
                }

                // Store the bomber class
                CBomber Bomber = (CBomber)s_ObjectManager.GetEnemy(ABCEnemy.eEnemyType.BOMBER);
                List<int> BomberIndexList = m_BomberIndexList[iObject];

                // Loop through each contained bomber
                for (int iBomber = BomberIndexList.Count - 1; iBomber >= 0; --iBomber)
                {
                    // If the bomber is no longer alive
                    if (Bomber.IsObjectActive(BomberIndexList[iBomber]) == false)
                    {
                        // Remove the bomber from the index list
                        BomberIndexList.RemoveAt(iBomber);

                        // Increment the number of bombers needing creation
                        ++m_nBomberCount[iObject];

                        // Increment the delay until another fighter is spawned
                        m_fBomberTimer[iObject] += 5.0f;
                    }
                }

                // Decrement the bomber timer
                m_fBomberTimer[iObject] -= _fDeltaTime;

                // If a bomber is ready to launch
                if (m_nBomberCount[iObject] > 0 && m_fBomberTimer[iObject] < 0.0f 
                    && Bomber.GetActiveObjectCount() != Bomber.GetObjectCount())
                {
                    // Create a bomber
                    m_BomberIndexList[iObject].Add(Bomber.CreateEnemy(this, iObject));
                    Bomber.ScheduleForActivation(BomberIndexList[BomberIndexList.Count - 1]);
                    Bomber.ApplyForce(BomberIndexList[BomberIndexList.Count - 1], 
                        100.0f * Bomber.GetMass() * Vector3.Down);

                    // Reset the bomber timer and decrement the number of bombers remaining
                    m_fBomberTimer[iObject] = 1.5f;
                    --m_nBomberCount[iObject];
                }
            }

            // Update base members
            base.Update(_fDeltaTime);
        }

        protected override void FirePrimary(int _nIndex)
        {
            // Set the missile count
            m_nMissileCount[_nIndex] = 10;

            if (m_bBombersReleased[_nIndex] == false)
            {
                m_nBomberCount[_nIndex] = 5;
                m_bBombersReleased[_nIndex] = true;
            }
        }

        protected override void FireSecondary(int _nIndex)
        {
            // Set the damage for plasma
            m_fDamage = PLASMA_DAMAGE;

            s_ObjectManager.GetProjectile(ABCProjectile.eProjectileType.PLASMA)
                .CreateProjectile(this, _nIndex, new Vector3(-20.0f, 0.0f, -5.0f));
            s_ObjectManager.GetProjectile(ABCProjectile.eProjectileType.PLASMA)
                .CreateProjectile(this, _nIndex, new Vector3(20.0f, 0.0f, -5.0f));
        }
    }
}
